<template>
	<view class="tabs" :style="[{'background': tabsBgColor}, customStyle]">
		<view :id="id">
			<scroll-view scroll-x :scroll-left="scrollLeft" scroll-with-animation>
				<view class="tabs__scroll" :class="{'tabs__scroll-flex': !isScroll}">
					<view class="tabs__item" :id="'tabs__item-'+index" v-for="(item, index) in list" :key="index" @tap="clickTab(index)" :style="[tabItemStyle(index)]">
						{{ item[name] || item['name'] }}
						<view v-if="showLabel" class="tabs__label" :style="[tabLabelStyle, labelStyle(index)]">{{ item[label] }}</view>
					</view>
					<view class="tabs__bar" v-if="!hideBar" :style="[tabBarStyle]"></view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
	import { createUuid, addUnit } from '@/depend/js/function.js'
	
	export default {
		name: 'componentTabs',
		props: {
			isScroll: Boolean,
			themeColor: Boolean,
			list: {
				type: Array,
				default() {
					return []
				}
			},
			current: {
				type: [Number, String],
				default: 0
			},
			height: {
				type: [String, Number],
				default: 80
			},
			fontSize: {
				type: [String, Number],
				default: 30
			},
			duration: {
				type: [String, Number],
				default: 0.5
			},
			activeColor: String,
			color: {
				type: String,
				default: '#333'
			},
			barWidth: {
				type: [String, Number],
				default: 40
			},
			barHeight: {
				type: [String, Number],
				default: 6
			},
			gutter: {
				type: [String, Number],
				default: 30
			},
			bgColor: {
				type: String,
				default: '#ffffff'
			},
			name: {
				type: String,
				default: 'name'
			},
			showLabel: Boolean,
			label: {
				type: String,
				default: 'label'
			},
			activeItemStyle: {
				type: Object,
				default() {
					return {}
				}
			},
			itemStyle: {
				type: Object,
				default() {
					return {}
				}
			},
			hideBar: Boolean,
			barStyle: {
				type: Object,
				default() {
					return {}
				}
			},
			bold: Boolean,
			itemWidth: {
				type: [Number, String],
				default: 'auto'
			},
			loading: Boolean,
			tabLabelStyle: {
				type: Object,
				default() {
					return {}
				}
			},
			customStyle: {
				type: Object,
				default() {
					return {}
				}
			}
		},
		data() {
			return {
				scrollLeft: 0,
				tabQueryInfo: [],
				componentWidth: 0,
				scrollBarLeft: 0,
				parentLeft: 0,
				id: createUuid(32, 'id'),
				currentIndex: this.current,
				barFirstTimeMove: true
			}
		},
		watch: {
			listJson(to, from) {
				let n = JSON.parse(to)
				let o = JSON.parse(from)
				if(n.length !== o.length) {
					this.currentIndex = 0
					this.scrollByIndex()
				}
				setTimeout(() => {
					this.init()
				}, 300)
				// this.$nextTick(() => {
				// 	this.init()
				// })
			},
			current: {
				immediate: true,
				handler(to, from) {
					this.$nextTick(() => {
						this.currentIndex = to
						this.scrollByIndex()
					})
				}
			}
		},
		computed: {
			listJson() {
				return JSON.stringify(this.list)
			},
			tabsBgColor() {
				return this.themeColor ? this.$i.colorTheme : this.bgColor
			},
			tabBarStyle() {
				let style = {
					width: this.barWidth + 'rpx',
					height: this.barHeight + 'rpx',
					transform: `translate(${this.scrollBarLeft}px, -100%)`,
					'transition-duration': `${this.barFirstTimeMove ? 0 : this.duration}s`,
					'background-color': this.activeColor || (this.themeColor && '#ffffff') || this.$i.colorTheme,
					'border-radius': `${this.barHeight / 2}px`
				}
				Object.assign(style, this.barStyle)
				return style
			},
			tabItemStyle() {
				return (index) => {
					let style = {
						height: this.height + 'rpx',
						'line-height': this.height + 'rpx',
						'font-size': this.fontSize + 'rpx',
						'transition-duration': `${this.duration}s`,
						padding: this.isScroll ? `0 ${this.gutter}rpx` : '',
						flex: this.isScroll ? 'auto' : '1',
						width: addUnit(this.itemWidth)
					}
					if (index == this.currentIndex && this.bold) {
						style.fontWeight = 'bold'
					}
					style = Object.assign(style, this.itemStyle)
					if (index == this.currentIndex) {
						style.color = this.activeColor || (this.themeColor && '#ffffff') || this.$i.colorTheme
						style = Object.assign(style, this.activeItemStyle)
					} else {
						style.color = this.themeColor ? this.$i.colorThemeInfo : this.color
					}
					return style
				}
			},
			labelStyle() {
				return (index) => {
					let style = {}
					if (index == this.currentIndex) {
						style.color = this.activeColor || (this.themeColor && '#ffffff') || this.$i.colorTheme
					}
					return style
				}
			}
		},
		mounted() {
			this.init();
		},
		methods: {
			async init() {
				let tabRect = await this.$uGetRect('#' + this.id)
				this.parentLeft = tabRect.left
				this.componentWidth = tabRect.width
				setTimeout(() => {
					this.getTabRect()
				}, 500);
			},
			// 查询tab的布局信息
			getTabRect() {
				let query = uni.createSelectorQuery().in(this)
				for (let i = 0; i < this.list.length; i++) {
					query.select(`#tabs__item-${i}`).fields({
						size: true,
						rect: true
					})
				}
				query.exec((res) => {
					this.tabQueryInfo = res
					this.scrollByIndex()
				})
			},
			scrollByIndex() {
				// 活动item信息
				let tabInfo = this.tabQueryInfo[this.currentIndex]
				if (!tabInfo) return
				// 活动item宽度
				let tabWidth = tabInfo.width
				// 活动item到tab组件左边距离
				let offsetLeft = tabInfo.left - this.parentLeft
				// scroll-view滚动距离
				let scrollLeft = offsetLeft - ( this.componentWidth - tabWidth ) / 2
				this.scrollLeft = scrollLeft < 0 ? 0 : scrollLeft
				// 滑块移动距离
				this.scrollBarLeft = offsetLeft + (tabInfo.width - uni.upx2px(this.barWidth)) / 2
				if (this.barFirstTimeMove) {
					setTimeout(() => {
						this.barFirstTimeMove = false
					}, 100);
				}
			},
			clickTab(index) {
				if (this.loading || index == this.currentIndex) return
				this.$emit('change', index)
			}
		}
	}
</script>

<style scoped lang="scss">
	.tabs {
		scroll-view {
			width: 100%;
			white-space: nowrap;
			position: relative;
			&/deep/ ::-webkit-scrollbar {
				display: none;
				width: 0 !important;
				height: 0 !important;
				-webkit-appearance: none;
				background: transparent;
			}
		}
		&__scroll {
			position: relative;
			&-flex {
				display: flex;
				justify-content: space-between;
			}
		}
		&__item {
			position: relative;
			display: inline-block;
			text-align: center;
			transition-property: background-color, color;
		}
		&__label {
			font-size: 12px;
			color: #999;
		}
		&__bar {
			position: absolute;
			bottom: 0;
		}
	}
</style>
